/**
 * @author: Gene
 * @age: 永远18岁的美少年
 * @Email： yangjianyun@58.com
 * @date: 2021-12-04 19:50:27
 * @description:  ts 中的泛型
 */
// 创建一个 长度为 length 的数组, 里面的值用 value 填充.
// function createArray<T>(length: number, value: T): Array<T> {
//     let result: T[] = []
//     for (let i = 0; i < length; i++) {
//         result[i] = value
//     }
//     return result
// }
//
// let result = createArray<string>(3, 'X')
// console.log(result);

// 类数组
function sum() {
    let args: IArguments = arguments
    for (let i = 0; i < args.length; i++) {
        let arg = args[i];

    }

}

/** ======================== 泛型类  ==============================*/
class MyArray<T> {
    private list: T[] = []

    add(value: T) {
        this.list.push(value)
    }

    getMax(): T {
        return this.list[0]
    }
}

let array = new MyArray<number>()
array.add(1)
array.add(2)
array.add(3)
console.log(array.getMax());

/** ================= 泛型与 new 关键字 ==============*/
function factory<T>(type: { new(): T }): T {
    return new type()

}

class Person {
}

let p = factory<Person>(Person)
console.log(p);

/** ==================== 泛型接口 ================*/
interface Calculate {
    <T>(a: T, b: T): T
}

let sum1: Calculate = function <T>(a: T, b: T): T {
    return a
}
sum1<number>(1, 2)


/** =========  =============== 泛型可以写多个 ======================*/
function swap<T, K>(tuple: [T, K]): [K, T] {
    return [tuple[1], tuple[0]]
}

/** ========================m 默认泛型: 如果相传泛型就可以传, 不想传泛型也可以, 类似于默认参数 =============*/
function createArray<T>(length: number, value: T): Array<T> {
    let result: T[] = []
    for (let i = 0; i < length; i++) {
        result[i] = value
    }
    return result
}

let result = createArray<string>(3, 'X') // X 传过去的时候, 会进行类型判断
console.log(result);

/** ========================= 泛型约束  非常非常非常重要 =======================*/
interface LengthWise {
    length: number
}

// 非常非常非常重要. 约束泛型 T , 让其有 length 属性.
function logger<T extends LengthWise>(val: T) {
    console.log(val.length);
}

export {}
// 该看10 .compose 泛型了